﻿using MqLibrary;
using RabbitMQ.Client;
using RabbitMQ.Client.Content;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Web.Script.Serialization;
namespace RabbitMqService
{
    public class RabbitHelper<T> : IRabbitHelperr<T>
    {      

        public void InsertRabbitMq(RabbitTypeEnum Ratype,T InserMessage)
        {
            IDictionary dict2 = ConfigurationManager.GetSection("RabbitConnet") as IDictionary;            
            string exchange = "";//路由  
            string exchangeType = "direct";//交换模式  
            string routingKey = "rk";//路由关键字  
            //是否对消息队列持久化保存  
            bool persistMode = true;
            ConnectionFactory cf = new ConnectionFactory();
            string typequeue = "";
            if (Ratype == RabbitTypeEnum.Email) 
            {
                typequeue = "Email";
                exchange = "Email";
            }
            if (Ratype == RabbitTypeEnum.Message)
            {
                typequeue = "Message";
                exchange = "Message";
            }
            cf.UserName = dict2["username"].ToString();
            cf.Password = dict2["password"].ToString();
            cf.HostName = dict2["Ip"].ToString();           
            cf.RequestedHeartbeat = 0;
            //创建一个连接到具体总结点的连接  
            using (IConnection conn = cf.CreateConnection())
            {             //创建并返回一个新连接到具体节点的通道  
                using (IModel ch = conn.CreateModel())
                {
                    if (exchangeType != null)
                    {//声明一个路由  
                        ch.ExchangeDeclare(exchange, exchangeType);
                        ////声明一个队列  
                        //ch.QueueDeclare(typequeue, false, false);
                        //将一个队列和一个路由绑定起来。并制定路由关键字    
                        ch.QueueBind(typequeue, exchange, routingKey);
                    }
                    ///构造消息实体对象并发布到消息队列上  
                    IMapMessageBuilder b = new MapMessageBuilder(ch);
                    var target = b.Headers;
                    target["header"] = "DataModel";
                    var targerBody = b.Body;
                    JavaScriptSerializer js = new JavaScriptSerializer();
                    targerBody["body"] = js.Serialize(InserMessage); ;//这个才是具体的发送内容  
                    if (persistMode)
                    {
                        ((IBasicProperties)b.GetContentHeader()).DeliveryMode = 2;
                        //设定传输模式  
                    }
                    //写入  
                    ch.BasicPublish(exchange, routingKey, (IBasicProperties)b.GetContentHeader(), b.GetContentBody());                  
                }

            }
        }
        public T GetRabbitMq(RabbitTypeEnum Ratype)
        {
            IDictionary dict2 = ConfigurationManager.GetSection("RabbitConnet") as IDictionary;   
            string result = "";          
            ConnectionFactory cf = new ConnectionFactory();
            cf.UserName = dict2["username"].ToString();
            cf.Password = dict2["password"].ToString();
            cf.HostName = dict2["Ip"].ToString();            
            cf.RequestedHeartbeat = 0;
            string typequeue = "";
            if (Ratype == RabbitTypeEnum.Email) typequeue = "Email";
            if (Ratype == RabbitTypeEnum.Message) typequeue = "Message";
            //cf.Endpoint = new AmqpTcpEndpoint(uri);  
            using (IConnection conn = cf.CreateConnection())
            {
                using (IModel ch = conn.CreateModel())
                {
                    //普通使用方式BasicGet  
                    //noAck = true，不需要回复，接收到消息后，queue上的消息就会清除  
                    //noAck = false，需要回复，接收到消息后，queue上的消息不会被清除，  
                    //直到调用channel.basicAck(deliveryTag, false);   
                    //queue上的消息才会被清除 而且，在当前连接断开以前，其它客户端将不能收到此queue上的消息  

                    BasicGetResult res = ch.BasicGet(typequeue, false/*noAck*/);
                    if (res != null)
                    {

                        ch.BasicAck(res.DeliveryTag, false);
                        result = System.Text.UTF8Encoding.UTF8.GetString(res.Body);
                        result = result.Replace("\0", "");
                        result = result.Replace("body", "");
                        result = result.Replace("\n", "").Trim();                       

                    }                   
                    ch.Close();
                }
                conn.Close();
            }          
           
                JavaScriptSerializer js = new JavaScriptSerializer();
                if (!string.IsNullOrEmpty(result)) return js.Deserialize<T>(result.Substring(result.IndexOf('{')));
                return js.Deserialize<T>(result);
           
        }
    }
}
       